from flask import Flask, render_template, request, jsonify
import PyPDF2
import re
import os
import traceback
from io import BytesIO
from pdfminer.high_level import extract_text as pdfminer_extract_text

app = Flask(__name__)

# 设置上传文件大小限制为 16MB
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

def clean_amount(amount_str):
    """清理金额字符串，移除逗号和空格"""
    return amount_str.replace(',', '').replace(' ', '')

def extract_text_from_pdf(pdf_file):
    """从PDF文件中提取文本，使用多种方法尝试"""
    text = ""
    error_messages = []
    
    try:
        # 保存文件内容到内存中
        pdf_content = pdf_file.read()
        pdf_file.seek(0)  # 重置文件指针
        
        # 方法1：使用 pdfminer.six 读取
        try:
            text = pdfminer_extract_text(BytesIO(pdf_content))
            if text.strip():
                print("使用 pdfminer.six 成功提取文本")
        except Exception as e:
            error_messages.append(f"pdfminer.six提取错误: {str(e)}")
        
        # 如果没有提取到文本，尝试方法2：使用PyPDF2
        if not text.strip():
            try:
                pdf_reader = PyPDF2.PdfReader(BytesIO(pdf_content))
                for page in pdf_reader.pages:
                    try:
                        page_text = page.extract_text()
                        if page_text:
                            text += page_text + "\n"
                    except Exception as e:
                        error_messages.append(f"PyPDF2页面提取错误: {str(e)}")
            except Exception as e:
                error_messages.append(f"PyPDF2读取错误: {str(e)}")
    
    except Exception as e:
        error_messages.append(f"PDF处理总体错误: {str(e)}")
    
    return text, error_messages

def extract_invoice_info(pdf_file):
    """从PDF文件中提取发票号码和金额"""
    try:
        print(f"\n开始处理文件: {pdf_file.filename}")
        print("-" * 50)
        
        # 提取文本
        text, error_messages = extract_text_from_pdf(pdf_file)
        
        if error_messages:
            print("提取过程中的警告:")
            for msg in error_messages:
                print(f"- {msg}")
        
        if not text.strip():
            return {"error": "无法从PDF中提取文本"}
        
        print(f"提取的文本长度: {len(text)} 字符")
        print("提取的文本前200个字符:", text[:200])
        
        # 使用正则表达式匹配发票号码（20位数字）
        invoice_matches = re.finditer(r'\d{20}', text)
        invoice_numbers = [match.group() for match in invoice_matches]
        
        if invoice_numbers:
            invoice_number = invoice_numbers[0]  # 使用第一个匹配的发票号码
            print(f"找到的所有发票号码: {invoice_numbers}")
            print(f"使用的发票号码: {invoice_number}")
        else:
            invoice_number = "未找到发票号码"
            print("未找到20位发票号码")

        # 匹配所有金额
        # 使用更灵活的正则表达式
        amount_patterns = [
            r'[¥￥]\s*([\d,]+\.?\d{0,2})',  # 标准格式：￥1,234.56
            r'人民币\s*([\d,]+\.?\d{0,2})',  # "人民币"后面的金额
            r'金额[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})',  # "金额："后面的数字
            r'合计[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})',   # "合计："后面的数字
            r'小写[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})',   # "小写："后面的数字
            r'大写[：:].+?小写[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})',  # 大写后面接小写的金额
            r'金额合计[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})',  # "金额合计："后面的数字
            r'价税合计[：:]\s*[¥￥]?\s*([\d,]+\.?\d{0,2})'   # "价税合计："后面的数字
        ]
        
        all_amounts = []
        for pattern in amount_patterns:
            matches = re.finditer(pattern, text)
            for match in matches:
                amount_str = match.group(1)
                print(f"匹配到金额 (使用模式 {pattern}): {amount_str}")
                all_amounts.append(amount_str)
        
        print(f"找到的所有原始金额: {all_amounts}")
        
        if all_amounts:
            # 清理金额字符串并转换为浮点数
            cleaned_amounts = []
            for amount in all_amounts:
                try:
                    cleaned_amount = clean_amount(amount)
                    float_amount = float(cleaned_amount)
                    cleaned_amounts.append(float_amount)
                    print(f"处理金额: {amount} -> {cleaned_amount} -> {float_amount}")
                except ValueError as e:
                    print(f"金额转换错误: {amount}, 错误: {str(e)}")
                    continue
            
            if cleaned_amounts:
                max_amount = max(cleaned_amounts)
                amount = f"￥{max_amount:.2f}"
                print(f"清理后的所有金额: {cleaned_amounts}")
                print(f"最大金额: {amount}")
            else:
                amount = "未找到有效金额"
        else:
            amount = "未找到金额"
            print("未找到任何金额")
        
        print("-" * 50)
        return {
            "invoice_number": invoice_number,
            "amount": amount
        }
    except Exception as e:
        print(f"处理过程中发生错误: {str(e)}")
        print(f"错误详情: {traceback.format_exc()}")
        return {
            "error": f"处理PDF时出错: {str(e)}"
        }

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload():
    if 'files[]' not in request.files:
        return jsonify({"error": "没有选择文件"})

    files = request.files.getlist('files[]')
    results = []

    for file in files:
        if file.filename == '':
            continue
        
        if file and file.filename.lower().endswith('.pdf'):
            result = extract_invoice_info(file)
            result['filename'] = file.filename
            results.append(result)

    return jsonify(results)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True) 